#ifndef MATH_HPP
#define MATH_HPP

namespace math
{
template <typename T>
constexpr T abs(T value);
template <typename T>
constexpr T log2(T value);
template <typename T>
constexpr T min(T first, T second);
template <typename T>
constexpr T max(T first, T second);

}

namespace math
{

template <typename T>
constexpr T abs(T value)
{
	return value >= static_cast<T>(0) ? value : -value;
}

template <typename T>
constexpr T log2(T value)
{
	constexpr T zero{static_cast<T>(0U)}, two{static_cast<T>(2U)};
	T res{zero};
	while((value /= two) > zero)
		++res;
	return res;
}

template <typename T>
constexpr T min(T first, T second)
{
	return first <= second ? first : second;
}

template <typename T>
constexpr T max(T first, T second)
{
	return first >= second ? first : second;
}

}

#endif
